home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / perl / perl5a1.lha / perl5alpha1 / av.c < prev    next >
C/C++ Source or Header  |  1993-07-31  |  6KB  |  335 lines

  1. /* $RCSfile: array.c,v $$Revision: 4.1 $$Date: 92/08/07 17:18:22 $
  2.  *
  3.  *    Copyright (c) 1991, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    array.c,v $
  9.  * Revision 4.1  92/08/07  17:18:22  lwall
  10.  * Stage 6 Snapshot
  11.  * 
  12.  * Revision 4.0.1.3  92/06/08  11:45:05  lwall
  13.  * patch20: Perl now distinguishes overlapped copies from non-overlapped
  14.  * 
  15.  * Revision 4.0.1.2  91/11/05  16:00:14  lwall
  16.  * patch11: random cleanup
  17.  * patch11: passing non-existend array elements to subrouting caused core dump
  18.  * 
  19.  * Revision 4.0.1.1  91/06/07  10:19:08  lwall
  20.  * patch4: new copyright notice
  21.  * 
  22.  * Revision 4.0  91/03/20  01:03:32  lwall
  23.  * 4.0 baseline.
  24.  * 
  25.  */
  26.  
  27. #include "EXTERN.h"
  28. #include "perl.h"
  29.  
  30. SV**
  31. av_fetch(ar,key,lval)
  32. register AV *ar;
  33. I32 key;
  34. I32 lval;
  35. {
  36.     SV *sv;
  37.  
  38.     if (key < 0 || key > AvFILL(ar)) {
  39.     if (lval && key >= 0) {
  40.         if (AvREAL(ar))
  41.         sv = NEWSV(5,0);
  42.         else
  43.         sv = sv_mortalcopy(&sv_undef);
  44.         return av_store(ar,key,sv);
  45.     }
  46.     else
  47.         return 0;
  48.     }
  49.     if (!AvARRAY(ar)[key]) {
  50.     if (lval) {
  51.         sv = NEWSV(6,0);
  52.         return av_store(ar,key,sv);
  53.     }
  54.     return 0;
  55.     }
  56.     return &AvARRAY(ar)[key];
  57. }
  58.  
  59. SV**
  60. av_store(ar,key,val)
  61. register AV *ar;
  62. I32 key;
  63. SV *val;
  64. {
  65.     I32 tmp;
  66.     SV** ary;
  67.  
  68.     if (key < 0)
  69.     return 0;
  70.     if (key > AvMAX(ar)) {
  71.     I32 newmax;
  72.  
  73.     if (AvALLOC(ar) != AvARRAY(ar)) {
  74.         tmp = AvARRAY(ar) - AvALLOC(ar);
  75.         Move(AvARRAY(ar), AvALLOC(ar), AvMAX(ar)+1, SV*);
  76.         Zero(AvALLOC(ar)+AvMAX(ar)+1, tmp, SV*);
  77.         AvMAX(ar) += tmp;
  78.         AvARRAY(ar) -= tmp;
  79.         if (key > AvMAX(ar) - 10) {
  80.         newmax = key + AvMAX(ar);
  81.         goto resize;
  82.         }
  83.     }
  84.     else {
  85.         if (AvALLOC(ar)) {
  86.         newmax = key + AvMAX(ar) / 5;
  87.           resize:
  88.         Renew(AvALLOC(ar),newmax+1, SV*);
  89.         Zero(&AvALLOC(ar)[AvMAX(ar)+1], newmax - AvMAX(ar), SV*);
  90.         }
  91.         else {
  92.         newmax = key < 4 ? 4 : key;
  93.         Newz(2,AvALLOC(ar), newmax+1, SV*);
  94.         }
  95.         AvARRAY(ar) = AvALLOC(ar);
  96.         AvMAX(ar) = newmax;
  97.     }
  98.     }
  99.     ary = AvARRAY(ar);
  100.     if (AvREAL(ar)) {
  101.     if (AvFILL(ar) < key) {
  102.         while (++AvFILL(ar) < key) {
  103.         if (ary[AvFILL(ar)] != Nullsv) {
  104.             sv_free(ary[AvFILL(ar)]);
  105.             ary[AvFILL(ar)] = Nullsv;
  106.         }
  107.         }
  108.     }
  109.     if (ary[key])
  110.         sv_free(ary[key]);
  111.     }
  112.     ary[key] = val;
  113.     return &ary[key];
  114. }
  115.  
  116. AV *
  117. newAV()
  118. {
  119.     register AV *ar;
  120.  
  121.     Newz(1,ar,1,AV);
  122.     SvREFCNT(ar) = 1;
  123.     sv_upgrade(ar,SVt_PVAV);
  124.     AvREAL_on(ar);
  125.     AvALLOC(ar) = AvARRAY(ar) = 0;
  126.     AvMAX(ar) = AvFILL(ar) = -1;
  127.     return ar;
  128. }
  129.  
  130. AV *
  131. av_make(size,strp)
  132. register I32 size;
  133. register SV **strp;
  134. {
  135.     register AV *ar;
  136.     register I32 i;
  137.     register SV** ary;
  138.  
  139.     Newz(3,ar,1,AV);
  140.     SvREFCNT(ar) = 1;
  141.     sv_upgrade(ar,SVt_PVAV);
  142.     New(4,ary,size+1,SV*);
  143.     AvALLOC(ar) = ary;
  144.     Zero(ary,size,SV*);
  145.     AvREAL_on(ar);
  146.     AvARRAY(ar) = ary;
  147.     AvFILL(ar) = size - 1;
  148.     AvMAX(ar) = size - 1;
  149.     for (i = 0; i < size; i++) {
  150.     if (*strp) {
  151.         ary[i] = NEWSV(7,0);
  152.         sv_setsv(ary[i], *strp);
  153.     }
  154.     strp++;
  155.     }
  156.     return ar;
  157. }
  158.  
  159. AV *
  160. av_fake(size,strp)
  161. register I32 size;
  162. register SV **strp;
  163. {
  164.     register AV *ar;
  165.     register SV** ary;
  166.  
  167.     Newz(3,ar,1,AV);
  168.     SvREFCNT(ar) = 1;
  169.     sv_upgrade(ar,SVt_PVAV);
  170.     New(4,ary,size+1,SV*);
  171.     AvALLOC(ar) = ary;
  172.     Copy(strp,ary,size,SV*);
  173.     AvREAL_off(ar);
  174.     AvARRAY(ar) = ary;
  175.     AvFILL(ar) = size - 1;
  176.     AvMAX(ar) = size - 1;
  177.     while (size--) {
  178.     if (*strp)
  179.         SvTEMP_off(*strp);
  180.     strp++;
  181.     }
  182.     return ar;
  183. }
  184.  
  185. void
  186. av_clear(ar)
  187. register AV *ar;
  188. {
  189.     register I32 key;
  190.  
  191.     if (!ar || !AvREAL(ar) || AvMAX(ar) < 0)
  192.     return;
  193.     /*SUPPRESS 560*/
  194.     if (key = AvARRAY(ar) - AvALLOC(ar)) {
  195.     AvMAX(ar) += key;
  196.     AvARRAY(ar) -= key;
  197.     }
  198.     for (key = 0; key <= AvMAX(ar); key++)
  199.     sv_free(AvARRAY(ar)[key]);
  200.     AvFILL(ar) = -1;
  201.     Zero(AvARRAY(ar), AvMAX(ar)+1, SV*);
  202. }
  203.  
  204. void
  205. av_undef(ar)
  206. register AV *ar;
  207. {
  208.     register I32 key;
  209.  
  210.     if (!ar)
  211.     return;
  212.     /*SUPPRESS 560*/
  213.     if (key = AvARRAY(ar) - AvALLOC(ar)) {
  214.     AvMAX(ar) += key;
  215.     AvARRAY(ar) -= key;
  216.     }
  217.     if (AvREAL(ar)) {
  218.     for (key = 0; key <= AvMAX(ar); key++)
  219.         sv_free(AvARRAY(ar)[key]);
  220.     }
  221.     Safefree(AvALLOC(ar));
  222.     AvALLOC(ar) = AvARRAY(ar) = 0;
  223.     AvMAX(ar) = AvFILL(ar) = -1;
  224. }
  225.  
  226. void
  227. av_free(ar)
  228. AV *ar;
  229. {
  230.     av_undef(ar);
  231.     Safefree(ar);
  232. }
  233.  
  234. bool
  235. av_push(ar,val)
  236. register AV *ar;
  237. SV *val;
  238. {
  239.     return av_store(ar,++(AvFILL(ar)),val) != 0;
  240. }
  241.  
  242. SV *
  243. av_pop(ar)
  244. register AV *ar;
  245. {
  246.     SV *retval;
  247.  
  248.     if (AvFILL(ar) < 0)
  249.     return Nullsv;
  250.     retval = AvARRAY(ar)[AvFILL(ar)];
  251.     AvARRAY(ar)[AvFILL(ar)--] = Nullsv;
  252.     return retval;
  253. }
  254.  
  255. void
  256. av_popnulls(ar)
  257. register AV *ar;
  258. {
  259.     register I32 fill = AvFILL(ar);
  260.  
  261.     while (fill >= 0 && !AvARRAY(ar)[fill])
  262.     fill--;
  263.     AvFILL(ar) = fill;
  264. }
  265.  
  266. void
  267. av_unshift(ar,num)
  268. register AV *ar;
  269. register I32 num;
  270. {
  271.     register I32 i;
  272.     register SV **sstr,**dstr;
  273.  
  274.     if (num <= 0)
  275.     return;
  276.     if (AvARRAY(ar) - AvALLOC(ar) >= num) {
  277.     AvMAX(ar) += num;
  278.     AvFILL(ar) += num;
  279.     while (num--)
  280.         *--AvARRAY(ar) = Nullsv;
  281.     }
  282.     else {
  283.     (void)av_store(ar,AvFILL(ar)+num,(SV*)0);    /* maybe extend array */
  284.     dstr = AvARRAY(ar) + AvFILL(ar);
  285.     sstr = dstr - num;
  286. #ifdef BUGGY_MSC5
  287.  # pragma loop_opt(off)    /* don't loop-optimize the following code */
  288. #endif /* BUGGY_MSC5 */
  289.     for (i = AvFILL(ar) - num; i >= 0; i--) {
  290.         *dstr-- = *sstr--;
  291. #ifdef BUGGY_MSC5
  292.  # pragma loop_opt()    /* loop-optimization back to command-line setting */
  293. #endif /* BUGGY_MSC5 */
  294.     }
  295.     Zero(AvARRAY(ar), num, SV*);
  296.     }
  297. }
  298.  
  299. SV *
  300. av_shift(ar)
  301. register AV *ar;
  302. {
  303.     SV *retval;
  304.  
  305.     if (AvFILL(ar) < 0)
  306.     return Nullsv;
  307.     retval = *AvARRAY(ar);
  308.     *(AvARRAY(ar)++) = Nullsv;
  309.     AvMAX(ar)--;
  310.     AvFILL(ar)--;
  311.     return retval;
  312. }
  313.  
  314. I32
  315. av_len(ar)
  316. register AV *ar;
  317. {
  318.     return AvFILL(ar);
  319. }
  320.  
  321. void
  322. av_fill(ar, fill)
  323. register AV *ar;
  324. I32 fill;
  325. {
  326.     if (fill < 0)
  327.     fill = -1;
  328.     if (fill <= AvMAX(ar))
  329.     AvFILL(ar) = fill;
  330.     else {
  331.     AvFILL(ar) = fill - 1;        /* don't clobber in-between values */
  332.     (void)av_store(ar,fill,Nullsv);
  333.     }
  334. }
  335.